package smartt.styy.auth.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;
import smartt.styy.auth.biz.ThridLoginInfoBiz;
import smartt.styy.auth.biz.TypeRelationBiz;
import smartt.styy.auth.biz.UserBiz;
import smartt.styy.auth.constants.ServerConstants;
import smartt.styy.auth.model.entity.TbAuUser;
import smartt.styy.auth.model.entity.TbThridLoginInfo;
import smartt.styy.auth.model.entity.TbTypeRelation;
import smartt.styy.auth.model.jwt.JWTInfo;
import smartt.styy.auth.model.request.JwtAuthenticationRequest;
import smartt.styy.auth.model.request.LoginVo;
import smartt.styy.auth.model.request.ThirdLoginReq;
import smartt.styy.auth.model.request.ThirdRegisterReq;
import smartt.styy.auth.model.request.UserTermDeviceEntity;
import smartt.styy.auth.model.response.ThridLoginRsp;
import smartt.styy.auth.model.utils.JwtTokenUtil;
import smartt.styy.auth.service.UserService;
import smartt.styy.auth.util.DESEncrypt;
import smartt.styy.auth.util.IdGenerator;
import smartt.styy.auth.util.MD5Util;
import smartt.styy.auth.util.PwdUtils;
import smartt.styy.common.bean.AnonymousInfo;
import smartt.styy.common.bean.UserInfo;
import smartt.styy.common.constant.RestCodeConstants;
import smartt.styy.common.exception.BaseException;

@Slf4j
@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	public UserBiz userBiz;
	
	@Autowired
	private TypeRelationBiz typeRelationBiz;
	
	@Autowired
	private ThridLoginInfoBiz thridLoginInfoBiz;
	
	@Autowired
	private JwtTokenUtil jwtTokenUtil;
	
	@Autowired
	private IdGenerator idGenerator;
	
	@Value("${3des.key}")
	private String desKey;
	
	/**
	 * 匿名登录
	 * */
	@Override
	public AnonymousInfo loginByTerm(UserTermDeviceEntity param) throws Exception{
		AnonymousInfo anonymousInfo =new AnonymousInfo();
		try {
			//匿名用户登录
			anonymousInfo = userBiz.loginByTerm(param);
			
			//用户类型关系表判断有无记录
			Map<String,Object> reqMap = new HashMap<String,Object>();
			reqMap.put("userId", anonymousInfo.getId());
			reqMap.put("userTypeId", param.getUserType());
			List<TbTypeRelation> lst = typeRelationBiz.selectByQuery(reqMap);
			//无记录
			if(lst.size() < 1){
				TbTypeRelation typeRelation = new TbTypeRelation();
				typeRelation.setUserId(anonymousInfo.getId());
				typeRelation.setUsertypeId(param.getUserType());
				typeRelationBiz.insertSelective(typeRelation);
			}
			
		} catch (Exception e) {
			return null;
		}
		return anonymousInfo;
	}

	/**
	 * 第三方登录
	 * */
	@Override
	public ThridLoginRsp loginByThirdAppAccount(ThirdLoginReq param) throws Exception{
		
		ThridLoginRsp accVo = new ThridLoginRsp();
		Integer thridId = null;
		try {
			
			Map<String,Object> reqMap = new HashMap<String,Object>();
			reqMap.put("thridLoginType", param.getThridAccountType());
			reqMap.put("thridAccount", param.getThridAccount());
			TbThridLoginInfo thridLoginInfo = thridLoginInfoBiz.findByThirdPlatformTypeAndThirdOpenId(reqMap);
			TbAuUser auUser = new TbAuUser();
			//判断有没有之前登录过
			if(thridLoginInfo != null){
				thridId = thridLoginInfo.getId();
				Integer userId = thridLoginInfo.getUserId();
				if(null != userId){
					auUser = userBiz.selectById(userId);
					BeanUtils.copyProperties(auUser, accVo);
					//判断用户类型关系表是否有记录
					Map<String,Object> reqMap2 =new HashMap<String,Object>();
					reqMap2.put("userId", userId);
					reqMap2.put("userTypeId", param.getUserType());
					List<TbTypeRelation> list = typeRelationBiz.selectByQuery(reqMap2);
					if(list.size()< 1){
						log.warn("[用户注册]-[第三方登录] ,该第三方用户登录，用户类型不匹配，请稍后再试！");
						throw new BaseException("[用户注册]-[第三方登录]--该第三方用户登录，用户类型不匹配-错误。",RestCodeConstants.THROW_ERROR_CODE);
					}
					accVo.setUserId(DESEncrypt.encryptMode(desKey,userId.toString()));
					//注册返回token
					String token = jwtTokenUtil.generateToken(new JWTInfo(auUser.getUsername(), 
							userId.toString() + "", "",param.getUserType()+"",auUser.getTelPhone()));
					accVo.setToken(token);
				}else{
					accVo.setUserId("");
					accVo.setToken("");
				}
				
			}else{
				log.warn("[用户注册]-[第三方登录]--未查询到第三方账号信息，需要完成第二步绑定手机号！");
				thridLoginInfo = new TbThridLoginInfo();
				BeanUtils.copyProperties(param, thridLoginInfo);
				thridLoginInfo.setSex(param.getSex());
				thridLoginInfo.setThridInfo(param.getThridInfo());
				thridLoginInfo.setThridLogoUrl(param.getThridLogoUrl());
				thridLoginInfo.setThridNickName(param.getThridNickName());
				thridLoginInfo.setThridAccount(param.getThridAccount());
				thridLoginInfo.setThridLoginType(param.getThridAccountType());
				
				thridLoginInfoBiz.insertSelective(thridLoginInfo);
				thridId = thridLoginInfo.getId();
				accVo.setUserId("");
				accVo.setToken("");
			}
			accVo.setNickName(param.getThridNickName());
			accVo.setStatus(ServerConstants.USER_STATUS_1);
			accVo.setThirdAccount(param.getThridAccount());
			accVo.setThridId(thridId);
			accVo.setThridLoginType(param.getThridAccountType());
			accVo.setUserType(param.getUserType());
			
		} catch (Exception e) {
			log.error("[用户注册]-[第三方登录] ,第三方用户登录，用户类型不匹配，请稍后再试！");
			throw new BaseException("[用户注册]-[第三方登录]--第三方用户登录，异常message:"+e.getMessage(),RestCodeConstants.THROW_ERROR_CODE);
		}
		
		return accVo;
	}

	/**
	 * 第三方登录第二步
	 * */
	@Override
	public Integer updateAccountInfoFromThirdAPP(ThirdRegisterReq param) throws Exception{
		Integer userId = null;
		try {
			
			//判断手机号对于的账号是否存在
			TbAuUser existUser = userBiz.selectByUserName(param.getMobile());
			if(null != existUser){
				userId = existUser.getId();
			}else{
				//用户表插入数据
				TbAuUser auUser = new TbAuUser();
				auUser.setUsername(param.getMobile());
				auUser.setTelPhone(param.getMobile());
				auUser.setNickName(idGenerator.nextId());
				auUser.setIpAddr(param.getIp());
				userBiz.insertSelective(auUser);
				userId =auUser.getId();
			}
			
			//用户类型关系表插入
			TbTypeRelation typeRelation = new TbTypeRelation();
			typeRelation.setUserId(userId);
			typeRelation.setUsertypeId(param.getUserType());
			typeRelationBiz.insertSelective(typeRelation);
			
			//进行用户绑定-更新
			TbThridLoginInfo thridLoginInfo = new TbThridLoginInfo();
			thridLoginInfo.setId(param.getThridId());
			thridLoginInfo.setUserId(userId);
			thridLoginInfoBiz.updateSelectiveById(thridLoginInfo);
		} catch (Exception e) {
			log.error("[用户注册]-[第三方登录第二步] ,第三方登录第二步，操作失败！");
			throw new BaseException("[用户注册]-[第三方登录]--第三方登录第二步，操作失败，异常message:"+e.getMessage(),RestCodeConstants.THROW_ERROR_CODE);
		}
		return userId;
	}

	/**
	 * 手机号+密码登录
	 * */
	@Override
	public TbAuUser loginByPhoneAndPassword(LoginVo loginVo) throws Exception{
		TbAuUser auUser =new TbAuUser();
		//获取用户
		try {
			Map<String,Object> reqMap = new HashMap<String,Object>();
			reqMap.put("username", loginVo.getMobile());
			reqMap.put("status", ServerConstants.USER_STATUS_1);
			auUser = userBiz.selectUserInfoByParams(reqMap);
			
			if(auUser == null){
				log.warn("[UserBiz][loginByMobileAndPasswd]，用户手机号+密码登录，查询用户不存在！");
				return null;
			}
			
			String dbPassword = PwdUtils.generateDbPwd(loginVo.getMobile(),loginVo.getPasswd());
			String rsaPwd = MD5Util.encrypt(dbPassword);
			if(!auUser.getPassword().equals(rsaPwd)){
				log.warn("用户手机号+密码登录，用户密码不正确！");
				return null;
			}
			
		} catch (Exception e) {
			log.error("[UserBiz][loginByMobileAndPasswd]，用户手机号+密码登录异常，错误信息message:"+e.getMessage());
			throw new BaseException("[UserBiz][validate]，用户手机号+密码登录异常，错误信息message:"+e.getMessage(),
					RestCodeConstants.TOKEN_ERROR_CODE);
		}
			
		return auUser;
	}

	/**
	 * 校验userType
	 * */
	@Override
	public Boolean veritfyUserType(Map<String,Object> reqMap) throws Exception{
		Boolean result =false;
		List<TbTypeRelation> list = typeRelationBiz.selectByQuery(reqMap);
		if(list.size()< 1){
			log.warn("[用户注册]-[第三方登录] ,该第三方用户登录，用户类型不匹配，请稍后再试！");
			return result;
		}
		result =true;
		return result;
	}

	/**
	 * 用户验证
	 * */
	@Override
	public UserInfo validate(JwtAuthenticationRequest authenticationRequest) throws BaseException {
		UserInfo info = new UserInfo();
		try {
			Map<String,Object> reqMap = new HashMap<String,Object>();
			String dbPassword = PwdUtils.generateDbPwd(authenticationRequest.getUsername(),authenticationRequest.getPassword());
			String rsaPwd = MD5Util.encrypt(dbPassword);
			reqMap.put("username", authenticationRequest.getUsername());
			reqMap.put("password", rsaPwd);
			
			TbAuUser userVo = userBiz.selectUserInfoByParams(reqMap);
			if(null == userVo){
				return null;
			}
			reqMap = new HashMap<String,Object>();
			reqMap.put("userId", userVo.getId());
			reqMap.put("userType", authenticationRequest.getUserType());
			List<TbTypeRelation> lst = typeRelationBiz.selectByQuery(reqMap);
			if(lst.size()<1){
				return null;
			}
			
			BeanUtils.copyProperties(userVo, info);
			info.setId(userVo.getId().toString());
			info.setUserTypes(authenticationRequest.getUserType().toString());
		} catch (Exception e) {
			log.error("[UserBiz][validate]，用户账号密码及用户类型判断异常，错误信息message:"+e.getMessage());
			throw new BaseException("[UserBiz][validate]，用户账号密码及用户类型判断异常，错误信息message:"+e.getMessage(),RestCodeConstants.TOKEN_ERROR_CODE);
		}
        
        return info;
		
	}

	/**
	 * 手机重置密码
	 * */
	@Override
	public Boolean resetPwdByPhoneNum(String moblie, String newPwd) throws BaseException {

		Boolean result =false;
		try {
			//检查手机号是否存在
			Map<String,Object> reqMap = new HashMap<String,Object>();
			reqMap.put("username", moblie);
			reqMap.put("status", ServerConstants.USER_STATUS_1);
			TbAuUser auUser = userBiz.selectUserInfoByParams(reqMap);
			
			if(auUser == null){
				log.warn("[UserBiz][resetPwdByPhoneNum]，用户手机号+重置密码，查询用户不存在！");
				result = false;
			}
			
			TbAuUser updateAuUser = new TbAuUser();
			updateAuUser.setId(auUser.getId());
			updateAuUser.setUpdateAt(new Date());
			String dbPassword = PwdUtils.generateDbPwd(moblie,newPwd);
			String rsaPwd = MD5Util.encrypt(dbPassword);
			updateAuUser.setPassword(rsaPwd);
			userBiz.updateSelectiveById(updateAuUser);
			result = true;
		} catch (Exception e) {
			log.error("[UserBiz][resetPwdByPhoneNum]，用户手机号+重置密码，系统异常，错误message:"+e.getMessage());
			result = false;
		}
		
		return result;
	}

	/**
	 * 用户账号+密码，注册提交
	 * */
//	@Override
//	public TbAuUser userAccountAndPwdRegister(RegisterInfoReq param) throws Exception {
//		
//	}
	
}
